/**
 *
 * 来自：https://github.com/zx69/request-retransmission-chrome-extension/blob/master/myXHRScript.js
 * https://github.com/PengChen96/ajax-tools/blob/master/pageScripts/index.js
 *
 * 
 * 重写ajax方法，以便在请求结束后通知content_script
 * inject_script无法直接与background通信，所以先传到content_script，再通过他传到background
 */

console.log('====xhr_script load ====' );

(function(xhr) {
  console.log('==== new xhr====' );
  var XHR = xhr.prototype;
  var open = XHR.open;
  var send = XHR.send;

  // 对open进行patch 获取url和method
  XHR.open = function(method, url) {
    this._method = method;
    this._url = url;
    //console.log('==== new xhrXHR.open====' );
    return open.apply(this, arguments);
  };


  // 同send进行patch 获取responseData.
  XHR.send = function(postData) {
    //console.log('==== new xhrXHR.send====' );
    this.addEventListener('load', function() {
      var myUrl = this._url ? this._url.toLowerCase() : this._url;
      if(myUrl ) {
        if ( this.responseType != 'blob' && (this.responseType).indexOf('video')<0 && this.responseText) {
          // responseText is string or null
          try {
            var arr = this.responseText;
            //console.log('请求：', this._url );
            // 因为inject_script不能直接向background传递消息, 所以先传递消息到content_script
            window.postMessage({'url': this._url, "response": arr}, '*');

          } catch(err) {
            console.log(err);
            console.log("Error in responseType try catch");
          }
        }
      }
    });
    return send.apply(this, arguments);
  };
})(window._ahrealxhr?window._ahrealxhr:XMLHttpRequest);
//猎聘 XMLHttpRequest 使用window._ahrealxhr 代替 XMLHttpRequest  https://concat.lietou-static.com/fe-lib-pc/v6/femonitor/0.9.1/femonitor.min.5e335d71.js
//XMLHttpRequest || 

(function () {
  
    console.log('==== new fetch====' );
    
    //重写fetch
    const fetch_tools = {
        
        originalFetch: window.fetch.bind(window),
        myFetch: function (...args) {

            console.log('fetch==', args);

            const getOriginalResponse = async (stream) => {
              let text = '';
              const decoder = new TextDecoder('utf-8');
              const reader = stream.getReader();
              const processData = (result) => {
                if (result.done) {
                  return text;
                }
                const value = result.value;
                text += decoder.decode(value, {stream: true});
                return reader.read().then(processData);
              };
              return await reader.read().then(processData);
            }

            //const [requestUrl, data] = args;

            console.log('==requestUrl==', requestUrl);
            //console.log('==data==', data);

            let url = args[0];

            //测试
            if (url.includes('data.bilibili.com/v2/log/web') ) {
                console.log('###拒绝###');
                return Promise.reject('error');
            }

            return fetch_tools.originalFetch(...args).then(async  (response) => {
                
                console.log('==originalResponse==', response );

                const originalResponse = await getOriginalResponse(response.body);

                //window.postMessage({'url': this._url, "response": arr}, '*');
                window.postMessage({'url': response.url, "response": originalResponse }, '*');

                if (originalResponse) {

                  const stream = new ReadableStream({
                    start(controller) {
                      controller.enqueue(new TextEncoder().encode(originalResponse));
                      controller.close();
                    }
                  });

                  const newResponse = new Response(stream, {
                    headers: response.headers,
                    status: response.status,
                    statusText: response.statusText,
                  });

                  const responseProxy = new Proxy(newResponse, {
                    get: function (target, name) {
                      switch (name) {
                        case 'body':
                        case 'bodyUsed':
                        case 'ok':
                        case 'redirected':
                        case 'type':
                        case 'url':
                          return response[name];
                      }
                      return target[name];
                    }
                  });

                  for (let key in responseProxy) {
                    if (typeof responseProxy[key] === 'function') {
                      responseProxy[key] = responseProxy[key].bind(newResponse);
                    }
                  }
                  
                  return responseProxy;
                }

                return response;
            });
        },
    }

    window.fetch = fetch_tools.myFetch;

})();

